//
// Created by shiminli on 2024/1/3.
//

#include "verify_codes.h"


VerifyCodesColumnName verify_codes::names;
vector<string> verify_codes::columns = {names.id, names.phone_number, names.platform, names.verify_code, names.duration, names.used, names.create_time};


long verify_codes::insert(VerifyCodes &data) {
    vector<string> insertColumns = {names.phone_number, names.platform, names.verify_code, names.duration, names.used, names.create_time};
    vector<ValuePair> values {ValuePair(false, data.phone_number), ValuePair(true, data.platform),
                              ValuePair(true, data.verify_code), ValuePair(false, to_string(data.duration)),
                              ValuePair(true, "0"),ValuePair(true, data.create_time, true),
    };
    string cmd = SQLBuilder::insertSql(names.tabName, insertColumns, values);
    int ret = SQLHelper::getInstance()->executeUpdate(cmd.c_str());
    return ret;
}

std::optional<VerifyCodes> verify_codes::queryById(const long &id) {
    string cmd = "SELECT * FROM "+names.tabName + " where "+names.id +"="+ to_string(id);
    MYSQL_RES *res = SQLHelper::getInstance()->executeQuery(cmd.c_str());
    unsigned int fields = mysql_num_fields(res);
    cout<<"queryById rowCount: "<< res->row_count <<endl;
    if (res->row_count < 1 || fields != columns.size()){
        return std::nullopt;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    VerifyCodes acc{};
    rowToStruct(row, acc);
    mysql_free_result(res);
    return acc;

}


std::optional<VerifyCodes> verify_codes::queryByPhoneNumber(const std::string &phone_number) {
    string cmd = "SELECT * FROM "+names.tabName + " where "+names.phone_number +"='"+ phone_number+"' and used=0 order by create_time desc limit 1";
    MYSQL_RES *res = SQLHelper::getInstance()->executeQuery(cmd.c_str());
    unsigned int fields = mysql_num_fields(res);
    cout<<"queryByPhoneNumber rowCount: "<< res->row_count <<endl;
    if (res->row_count < 1 || fields != columns.size()){
        return std::nullopt;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    VerifyCodes model{};
    rowToStruct(row, model);
    mysql_free_result(res);
    return model;
}

int verify_codes::updateUseByCode(std::string verify_code) {
    string cmd = "UPDATE "+names.tabName+" SET used=1 where "+names.verify_code +"='"+ verify_code+"'";
    int ret = SQLHelper::getInstance()->executeUpdate(cmd.c_str());
//    ret if (ret == 0)
    return ret == 0;
}

void verify_codes::rowToStruct(const MYSQL_ROW &row, VerifyCodes &model) {
    try {
        model.id = row[0] ? stol(row[0]) : 0;
        model.phone_number = row[1] ? row[1] : "";
        model.platform = row[2] ? row[2] : "";
        model.verify_code = row[3] ? row[3] : "";
        model.duration = row[4] ? stoi(row[4]) : -1;
        model.used = row[5] ? stoi(row[5]) : 0;
        model.create_time = row[6] ? row[6] : "";

    } catch (const std::exception& e) {
        // 处理转换异常，可以记录日志或者抛出异常
        // 这里简单地将所有字段置为空或者默认值
        model = VerifyCodes{0};
    }
}